/*
 * @Author: jiangyg email@jiangyg.com
 * @Date: 2022-08-14 15:31:12
 * @LastEditors: jiangyg email@jiangyg.com
 * @LastEditTime: 2022-11-26 19:57:08
 * @FilePath: /frontend/mall-frontend/src/components/data-table/src/data-table.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
// jsx用法 https://www.cnblogs.com/plum-nikolas/archive/2021/01/29/14344782.html
import http from "@/utils/httpRequest";
import criteria from "@/utils/criteria";
import { ref, defineComponent, getCurrentInstance } from "vue";

import { ElRow, ElCol, ElForm, ElCard, ElButton, ElButtonGroup, ElTable, ElTableColumn, ElPagination } from "element-plus";

export default defineComponent({
  name: "DataTable",

  props: {
    name: { type: String, required: true },
    title: String,
    // 是否初始化查询
    initLoad: { type: Boolean, default: false },
    // 请求地址
    url: { type: String, required: true },
    // 是否分页
    pagination: { type: Boolean, default: true },
    // 是否有复选框
    selection: { type: Boolean, default: true },
    // 查询参数
    criterias: {
      type: Object,
      default() {
        return undefined;
      },
    },
    // 默认排序
    defaultOrders: {
      type: Array,
      default() {
        return [];
      },
    }
  },

  setup() {
    // 表格加载状态
    const loading = ref(false);
    // 请求列表数据
    const dataList = ref([]);
    // 分页相关信息
    const pageSize = ref(10);
    const total = ref(0);
    const pageIndex = ref(1);
    // 排序字段
    const orders = ref([]);
    // 数据表格对象
    const dataTableRef = ref();
    // 查询表单对象
    const searchFormRef = ref();
    return { loading, dataList, pageSize, total, pageIndex, orders, dataTableRef, searchFormRef };
  },

  components: {
    ElForm,
    ElRow,
    ElCol,
    ElCard,
    ElTable,
    ElButton,
    ElButtonGroup,
    ElTableColumn,
    ElPagination,
  },

  /**
   * 组件渲染
   * @returns
   */
  render() {
    // 获取当前实例
    let instance = getCurrentInstance();
    // 定义表格内容
    let children = [];
    /****************** 查询条件部分 ****************/
    if (instance.slots.search) {
      let search = (
        <div class="dt-search clearfix">
          <el-row>
            <el-col span={20}>
              <el-form ref={(this.searchFormRef = ref())} v-model={this.criterias} inline={true} label-position="left" label-width="80px">
                {instance.slots.search(instance.props.criterias)}
              </el-form>
            </el-col>
            <el-col span={4}>
              <div class="dts-btn-group fr">
                <el-button type="primary" size="large" onClick={this.loadTableData}>
                  查询
                </el-button>
                <el-button size="large" onClick={this.resetQueryForm}>
                  重置
                </el-button>
              </div>
            </el-col>
          </el-row>
        </div>
      );
      children.push(search);
    }
    /********************* 工具栏部分 **********************/
    if (instance.slots.toolbar || instance.props.title) {
      let toolbar = (
        <div class="dt-toolbar clearfix">
          <el-row>
            <el-col span={12}>
              <label>{instance.props.title}</label>
            </el-col>
            <el-col span={12}>
              <div class="fr">
                {instance.slots.toolbar()}
              </div>
            </el-col>
          </el-row>
        </div>
      );
      children.push(toolbar);
    }
    /******************************* 数据表格部分 ****************************/
    let columns = [];
    // 是否存在复选框
    if (instance.props.selection) {
      columns.push(<el-table-column type="selection" header-align="center" align="center" width="50" />);
    }
    // 插槽列追加
    columns = columns.concat(instance.slots.default());
    let table = (
      <div class="dt-main">
        <el-table
          ref={(this.dataTableRef = ref())}
          border
          v-loading={this.loading}
          data={this.dataList}
          element-loading-text="拼命加载中"
          empty-text="木有数据啊~"
          onSortChange={this.sortChangeEvent}
          header-cell-style={{ textAlign: "center" }}
        >
          {columns}
        </el-table>
      </div>
    );
    children.push(table);
    /************************************* 数据分页部分 *************************************/
    if (instance.props.pagination) {
      let pagination = (
        <div class="dt-pagination">
          <el-pagination background layout="prev, pager, next" page-size={this.pageSize} total={this.total} onCurrentChange={this.currentChangeHandle} />
        </div>
      );
      children.push(pagination);
    }
    return <div class="data-table">{children}</div>;
  },

  methods: {
    // 构建动态查询参数模型
    buildCriteriasModel() {
      let cs = this.criterias;
      let arr = [];
      if (!cs) {
        return arr;
      }
      Object.keys(cs).forEach(function (key) {
        let val = cs[key];
        if (val === undefined || val === null || val === "") {
          return;
        }
        // 如果查询条件是 string 类型的话，则直等
        if (!(val instanceof Array || val instanceof Object)) {
          arr.push(criteria.eq(key, cs[key]));
          return;
        }
        if (val instanceof Array) {
          arr.push(criteria.bt(key, cs[key]));
          return;
        }
        let op = cs[key]["type"];
        arr.push(criteria[op](key, cs[key]["value"]));
      });
      return arr;
    },
    // 构建排序模型
    buildOrderModel() {
      let orders = [].concat(this.orders);
      if (orders.length === 0 && this.defaultOrders.length > 0) {
        orders = orders.concat(this.defaultOrders);
      }
      return orders;
    },
    // 获取数据列表
    loadTableData() {
      this.loading = true;
      http
        .post({
          url: this.url,
          data: {
            current: this.pageIndex,
            size: this.pageSize,
            criterias: this.buildCriteriasModel(),
            orders: this.buildOrderModel(),
          },
        })
        .then(({ data }) => {
          if (http.success(data)) {
            this.dataList = this.pagination ? data.body.records : data.body;
            this.total = this.pagination ? data.body.total : 0;
          } else {
            this.dataList = [];
            this.total = 0;
          }
          this.loading = false;
        });
    },
    // 重置查询表单
    resetQueryForm() {
      for (const key in this.criterias) {
        this.criterias[key] = "";
      }
    },
    // 获取表格选中数据
    getSelection() {
      return this.dataTableRef.getSelectionRows();
    },
    // 排序事件
    sortChangeEvent(option) {
      // TODO 待支持多列自定义排序
      this.orders = [];
      this.orders.push({ name: option.prop, asc: option.order === "ascending" });
      this.loadTableData();
    },
    // 获取表格数据
    getDataList() {
      return this.dataList;
    },
    // 每页数
    sizeChangeHandle(val) {
      this.pageSize = val;
      this.pageIndex = 1;
      this.loadTableData();
    },
    // 当前页
    currentChangeHandle(val) {
      this.pageIndex = val;
      this.loadTableData();
    },
  },

  // 配合 keep-alive 组件使用，组件激活时使用
  activated() {
    if (this.initLoad) {
      this.loadTableData();
    }
  },
});
